package atessitura;
import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.nio.channels.FileChannel;
import java.util.ArrayList;
import java.util.Scanner;
import java.util.StringTokenizer;

import javax.swing.JFrame;
import javax.swing.JOptionPane;



public class TFileManager 
{
	ArrayList<GuitarNote> [][] array;
	String OSName;
	
	
	
	public TFileManager (File file) throws FileNotFoundException // this constructor takes a text file for reading
	{
		System.out.println ("File reader created");
		readFromText(file);
		OSName = System.getProperty("os.name");
	}

	private void readFromText(File file) throws FileNotFoundException
	{
		Scanner scanner = new Scanner(file);		
		String tickString = scanner.nextLine(); // num ticks 
		tickString = tickString.substring(6);	//continued finding num ticks
		int ticks = Integer.parseInt(tickString); // all done, i now know how many ticks are in this song
		
		
		int trackNum = -1; // don't worry about this, but keep it at -1. makes the file reading catch everything
		String numTracks = scanner.nextLine(); // number of tracks to set up 2D array of arraylists (eww, that's Eden's fault)
		int n = Integer.parseInt(numTracks.substring(2,numTracks.length())); // the actual num of tracks
		
		array = new ArrayList [n][ticks]; // num tracks, num ticks, notes at tick
		ArrayList<GuitarNote> []temp = new ArrayList[ticks]; // this represents 1 track
		
		while (scanner.hasNextLine())
		{
			String str = scanner.nextLine();
			if (str.contains ("Track")) // if we must create a new track
			{
				if (trackNum!=-1) //not at the beginning of file
				{
					array[trackNum] = temp; // adds track to 2d array of arraylists
				}
				trackNum++; // move on to next track
				temp = new ArrayList[ticks]; //resets track
				continue; // skip the rest, move on to next line
			}
			StringTokenizer st = new StringTokenizer(str); // this will help me split up the parameters of a guitarNote
		    int stringNum = Integer.parseInt( st.nextToken());
		    int fret = Integer.parseInt(st.nextToken());
		    int startTime = Integer.parseInt(st.nextToken());
		    int duration = Integer.parseInt(st.nextToken());
		    int [] tuning = new int[6];
		    int index = 0;
		    while (st.hasMoreTokens()) // this sets up the tuning array, fear not it works fine
		    {
		    	tuning [index] = Integer.parseInt(st.nextToken());
		    	index++;
		    }		   
		    GuitarNote note = new GuitarNote (stringNum,fret,duration,startTime,tuning);
		    if (temp[startTime] == null) // if no current notes exist at this tick, then create a new arraylist to hold them
		    {
		    	ArrayList<GuitarNote> blah = new ArrayList<GuitarNote>();
		    	blah.add(note);
		    	temp[startTime] = blah;
		    }
		    else // add note to the tick
		    {
		    	temp[startTime].add(note);
		    }
		    
		    //System.out.println(note);
	     }
		array[trackNum]=temp;
		
		
	}
 
	public TFileManager (File midiFile, ArrayList<GuitarNote>[][] array , String songName) throws IOException
	// this constructor is used for filewriting
	{	
		OSName = System.getProperty("os.name");
		songName = songName.substring(0,songName.length()-4); //gets rid of the .mid
		System.out.println (midiFile.getAbsolutePath());
		
		File file;
		if (OSName.contains("Windows"))// this will be the text file that has all the notes for Windows
		{
			boolean success = (new File("C:/Program Files/Tessitura/Imported Songs/")).mkdirs();
			
			
			System.out.println ("we had success");
			file = new File("C:/Program Files/Tessitura/Imported Songs/" +songName + ".txt");
			
		}
		else//Mac
		{
			boolean success = (new File("/Applications/Tessitura/Imported Songs/")).mkdirs();
			file = new File ("/Applications/Tessitura/Imported Songs/" +songName+ ".txt");
		}
		 
		 
		boolean optionPane = false;
		if (file.exists()) 
		{
			optionPane = true;
			Object[] options = {"Yes",
                    "Rename",
                    "Cancel"};
			int n = JOptionPane.showOptionDialog(new JFrame(),
					"This file already exists, would you like to overwrite it?",
							"File exists",
							JOptionPane.YES_NO_CANCEL_OPTION,
							JOptionPane.QUESTION_MESSAGE,
							null,
							options,
							options[2]);
			if (n == 0)//  overwriting a file
			{
				
			}
			if (n == 1) // rename
			{
				System.out.println ("We must rename this file");
				songName = JOptionPane.showInputDialog("What would you like to name this file? Do not include file extensions");
				file = new File ("Imported Songs/" + songName+ ".txt");
				if (OSName.contains("Windows"))
				{
					file = new File ("C:/Program Files/Tessitura/Imported Songs/" + songName+ ".txt");
				}
				else
				{
					file = new File ("/Applications/Tessitura/Imported Songs/" + songName+ ".txt");
				}
				copyMidiFile(midiFile, songName);
				
			}
			if (n == 2)
			{
				System.out.println ("File did not save");
				copyMidiFile(midiFile, songName);
				return;
			}
		}
		else
		{
			file.createNewFile();
		}
		FileWriter fw = new FileWriter(file.getAbsoluteFile());
		BufferedWriter bw = new BufferedWriter(fw);
		
		
		writeFile(array, bw); // this part actually writes the data to the text file
		bw.close();
		if (!optionPane)
		{
			copyMidiFile(midiFile, songName);
		}
	
	}
	
	public ArrayList<GuitarNote> [][] readNotes ()
	{
		return array;
	}

	private void writeFile(ArrayList<GuitarNote>[][] array, BufferedWriter bw)	throws IOException 
	{
		int numTracks = array.length;
		
		int maxTickLength = Integer.MIN_VALUE;
		for (int x = 0; x < numTracks; x++)
		{
			int numTicks = array[x].length;
			maxTickLength =Math.max(maxTickLength, numTicks);
			
		}
		bw.write("Ticks=" + maxTickLength);
		bw.newLine();
		bw.write("n=" + numTracks);
		bw.newLine();
		//int numTicks= array[0].length+1;
		//bw.write("ticks="+numTicks);
		//bw.newLine();
		
		
		
		for (int x=0; x<array.length;x++)
		{
			bw.write("Track: " + x); // track #
			
			bw.newLine();
			for (int y = 0; y < array[x].length;y++) // this will loop through each tick
			{
				if (array[x] [y]== null) // if there's no note at this tic, do nothing
				{
				}
				else
				{
					for (GuitarNote note : array[x][y]) // if there are notes at this tic, we write all the important info of the note
					{
						
						bw.write(note.toString());
						bw.newLine();
					}
				}
			}
			//bw.newLine();
		}
	}
	
	public void copyMidiFile (File origMidi, String songName) throws IOException
	{
		File destFile;
		if (OSName.contains("Windows"))// this will be the text file that has all the notes for Windows
		{
			boolean success = (new File("C:/Program Files/Tessitura/Imported Midi")).mkdirs();
			
			
			System.out.println ("we had success");
			destFile = new File("C:/Program Files/Tessitura/Imported Midi/" +songName + ".mid");
			
		}
		else//Mac
		{
			boolean success = (new File("/Applications/Tessitura/Imported Midi")).mkdirs();
			destFile = new File ("/Applications/Tessitura/Imported Midi/" +songName+ ".mid");
		}
		
		
		//File destFile =new File("Imported Midi/" + songName + ".mid");
		if (!destFile.exists())
		{
			destFile.createNewFile();
		}
		
		FileChannel source = null;
		FileChannel destination = null;
		
		try {
			source = new FileInputStream(origMidi).getChannel();
			destination = new FileOutputStream (destFile).getChannel();
			destination.transferFrom(source, 0, source.size());
			
		}
		finally {
			if (source != null)
			{
				source.close();
			}
			if (destination !=null)
			{
				destination.close();
			}
		}
		
		
		
		/*InputStream inStream = null;
		OutputStream outStream = null;
	    try
	    {
	 
    	    File bfile =new File("Imported Midi/" + songName + ".mid");
	 
    	    inStream = new FileInputStream(origMidi);
    	    outStream = new FileOutputStream(bfile);
	 
    	    byte[] buffer = new byte[1024];
	 
	    	    int length;
	    	    //copy the file content in bytes 
	    	    while ((length = inStream.read(buffer)) > 0){
	 
	    	    	outStream.write(buffer, 0, length);
	 
	    	    }
	 
	    	    inStream.close();
	    	    outStream.close();
	 
	    	    //delete the original file
	    	    //afile.delete();
	 
	    
	 
	    	}catch(IOException e){
	    	    e.printStackTrace();
	    	}
	    */
	}
}
